#include "qupdatedialog.h"
#include "ui_qupdatedialog.h"

#include "../libs/shared/qprojectcore.h"
#include "../libs/core/qsoftcore.h"
#include "../libs/shared/host/qabstracthost.h"
#include "../libs/device/qdevicemanager.h"
#include "../libs/device/update/qserverupdate.h"
#include "../libs/device/qbasedefine.h"

#include <QFileDialog>
#include <QMessageBox>
#include <QDir>
#include <QApplication>
#include <QFileInfo>
#include <QProgressDialog>
#include <QMessageBox>
#include <QFile>

QUpdateDialog::QUpdateDialog(tagDeviceInfo *device, QWidget *parent) :
    QBaseDialog(parent),
    ui(new Ui::QUpdateDialog),
    m_device_info(device)
{
    ui->setupUi(this);

    QAbstractHost* host=QSoftCore::get_core()->get_project_core()->get_project_host();
    QString str;
    if(host!=NULL)
    {
        str=host->get_property_value("projectPath").toString();
    }
    ui->pathEdit->setText(str);

    QServerUpdate *update=QSoftCore::get_core()->get_device_manager()->get_update_server();

    connect(update,SIGNAL(failed()),this,SLOT(update_failed()));
    connect(update,SIGNAL(success()),this,SLOT(update_success()));
    connect(QSoftCore::get_core()->get_device_manager(),
            SIGNAL(device_offline(QString)),this,SLOT(offline(QString)));
}

QUpdateDialog::~QUpdateDialog()
{
    delete ui;
}

void QUpdateDialog::on_pathBtn_clicked()
{
    QString str=QFileDialog::getExistingDirectory(this,tr("Project Path"),QDir::currentPath());
    if(str!="")
    {
        ui->pathEdit->setText(str);
    }
}

void QUpdateDialog::on_cancelBtn_clicked()
{
    close();
}

void QUpdateDialog::on_okBtn_clicked()
{

    QString softPath=QApplication::applicationDirPath();
    QString osType=m_device_info->m_device_type;
    if(osType=="")
    {
        osType="Windows";
    }

    QSoftCore::get_core()->get_project_core()->save();
    QString name;
    if(ui->softBtn->isChecked())
    {
        QString basePath=softPath+"/update/"+osType+"/soft";
        int l=basePath.size()+1;
        QDir dir(basePath);
        QList<QFileInfo> list=dir.entryInfoList(QDir::Dirs| QDir::Files |QDir::NoDot|QDir::NoDotDot);
        QFileInfo info;
        while(list.size()>0)
        {
            info=list.first();
            list.removeFirst();
            if(info.isFile())
            {
                name=info.filePath().mid(l);
                QFile f(info.filePath());
                if(f.open(QFile::ReadOnly))
                {
                    QByteArray array=f.readAll();
                    m_file_data+=(name.toLocal8Bit());
                    file_data_append_number(1);
                    file_data_append_number(array.size());
                    m_file_data+=array;
                }
            }
            else if(info.isDir())
            {
                QDir d(info.filePath());
                list+=d.entryInfoList(QDir::Dirs| QDir::Files |QDir::NoDot|QDir::NoDotDot);
            }
        }
    }
    if(ui->pluginBtn->isChecked())
    {
        QString basePath=softPath+"/update/"+osType+"/plugin";
        int l=basePath.size()+1;
        QDir dir(basePath);
        QList<QFileInfo> list=dir.entryInfoList(QDir::Dirs| QDir::Files |QDir::NoDot|QDir::NoDotDot);
        QFileInfo info;
        while(list.size()>0)
        {
            info=list.first();
            list.removeFirst();
            if(info.isFile())
            {
                name=info.filePath().mid(l);
                QFile f(info.filePath());
                if(f.open(QFile::ReadOnly))
                {
                    QByteArray array=f.readAll();
                    m_file_data+=(name.toLocal8Bit());
                    file_data_append_number(2);
                    file_data_append_number(array.size());
                    m_file_data+=array;
                }
            }
            else if(info.isDir())
            {
                QDir d(info.filePath());
                list+=d.entryInfoList(QDir::Dirs| QDir::Files |QDir::NoDot|QDir::NoDotDot);
            }
        }
    }
    if(ui->proBtn->isChecked())
    {
        QString basePath=ui->pathEdit->text();
        if(basePath=="")
        {
            clear();
            return;
        }
        int l=basePath.size()+1;
        QDir dir(basePath);
        QList<QFileInfo> list=dir.entryInfoList(QDir::Dirs| QDir::Files |QDir::NoDot|QDir::NoDotDot);
        QFileInfo info;
        while(list.size()>0)
        {
            info=list.first();
            list.removeFirst();
            if(info.isFile())
            {
                name=info.filePath().mid(l);
                QFile f(info.filePath());
                if(f.open(QFile::ReadOnly))
                {
                    QByteArray array=f.readAll();
                    m_file_data+=(name.toLocal8Bit());
                    file_data_append_number(3);
                    file_data_append_number(array.size());
                    m_file_data+=array;
                }
            }
            else if(info.isDir())
            {
                QDir d(info.filePath());
                list+=d.entryInfoList(QDir::Dirs| QDir::Files |QDir::NoDot|QDir::NoDotDot);
            }
        }
    }
    if(m_file_data.size()>0)
    {
        uint sum=0;
        for(int i=0;i<m_file_data.size();i++)
        {
            sum+=(m_file_data.at(i)&0xff);
        }
        file_data_append_number(sum);

        QServerUpdate *update=QSoftCore::get_core()->get_device_manager()->get_update_server();
        int count=update->update(m_file_data,m_device_info);
        if(count>0)
        {
            QProgressDialog dlg(this,Qt::CustomizeWindowHint | Qt::WindowTitleHint);
            dlg.setWindowTitle(tr("Update"));
            dlg.setRange(0,count);
            dlg.setValue(0);
            dlg.setCancelButton(NULL);
            connect(update,SIGNAL(failed()),&dlg,SLOT(close()));
            connect(update,SIGNAL(success()),&dlg,SLOT(close()));
            connect(update,SIGNAL(position(int)),&dlg,SLOT(setValue(int)));
            dlg.exec();
        }
        clear();
        close();
    }
}

void QUpdateDialog::update_failed()
{
    if(m_device_info==NULL)
    {
        return;
    }
    QMessageBox::warning(this,tr("Warning"),tr("Update failed!"));
}

void QUpdateDialog::update_success()
{
    if(m_device_info==NULL)
    {
        return;
    }
    QMessageBox::critical(this,tr("Update"),tr("Update Success!"));
}

void QUpdateDialog::offline(const QString &uuid)
{
    if(uuid !="" && m_device_info!=NULL && uuid!=m_device_info->m_uuid)
    {
        return;
    }
    m_device_info=NULL;
    QMessageBox::critical(this,tr("Update"),tr("Device Offline!"));
    close();
}

void QUpdateDialog::file_data_append_number(int value)
{
    m_file_data.append((value>>24)&0xff);
    m_file_data.append((value>>16)&0xff);
    m_file_data.append((value>>8)&0xff);
    m_file_data.append(value&0xff);
}

void QUpdateDialog::clear()
{
    m_file_data.clear();
}
